#ifndef APP_DATA_STRUCTURE_BINARY_TREE_INCLUDE_BINARY_TREE_H
#define APP_DATA_STRUCTURE_BINARY_TREE_INCLUDE_BINARY_TREE_H

#include <iostream>
#include <memory>
#include <vector>

namespace DataStructure {
struct TreeNode {
    int32_t val_;
    TreeNode* left_;
    TreeNode* right_;

    TreeNode(int32_t val) : val_(val), left_(nullptr), right_(nullptr) {}
    TreeNode(int32_t val, TreeNode* left, TreeNode* right) 
        : val_(val), left_(left), right_(right) {}
};

class BinaryTree {
public:
    BinaryTree();
    ~BinaryTree();
    void Clear(TreeNode* node);
    void Insert(int32_t val);
    void PreOrderRecursion();
    void InOrderRecursion();
    void PostOrderRecursion();
    void PreOrderIterative();
    // void InOrderIterative();
    // void PostOrderIterative();
    TreeNode* SearchNode(int32_t val) const;
    int32_t GetHeight();
    int32_t GetSize();
    TreeNode* SearchNode(int32_t val);
    TreeNode* GetRoot() const;
    void SetRoot(TreeNode* node);

private:
    void PreOrderRecursionInner(TreeNode* node, std::vector<int32_t> &result);
    void InOrderRecursionInner(TreeNode* node, std::vector<int32_t> &result);
    void PostOrderRecursionInner(TreeNode* node, std::vector<int32_t> &result);
    TreeNode* SearchNodeInner(TreeNode* node, int32_t val) const;
    int32_t GetHeightInner(TreeNode* node);
    TreeNode* SearchNodeInner(TreeNode* node, int32_t val);
    int32_t GetSizeInner(TreeNode* node);

    TreeNode* root_;
};

// struct SmartPointerTreeNode {
//     int32_t val_;
//     std::unique_ptr<SmartPointerTreeNode> left_;
//     std::unique_ptr<SmartPointerTreeNode> right_;

//     SmartPointerTreeNode(int32_t val) : val_(val), left_(nullptr), right_(nullptr) {}
//     SmartPointerTreeNode(int32_t val, std::unique_ptr<SmartPointerTreeNode> left,
//         std::unique_ptr<SmartPointerTreeNode> right) 
//         : val_(val), left_(std::move(left)), right_(std::move(right)) {}
// };

// class SmartPointerBinaryTree {

// private:
//     std::unique_ptr<SmartPointerTreeNode> root_;
// };

} // namespace DataStructure
#endif // APP_DATA_STRUCTURE_BINARY_TREE_INCLUDE_BINARY_TREE_H